# -*- coding = utf-8 -*-
# @Time : 2023/3/12 7:45
# @Author : 龙王赘婿_彪少
# @File : mycom.py
# @Software: PyCharm

# 目标：
# 1、发送任意报文给指定串口
# 2、接收并显示报文
# 3、灵活加校验
import serial
import time
import struct
import binascii
import threading


class COM:
    __doc__ = ["https://blog.csdn.net/u010835747/article/details/111407089"]
    __doc__ += ["https://blog.csdn.net/weixin_39541869/article/details/110967865"]

    '''
    测试结论：
    在python中，实际写入write()中发送的数据形如：b'\x01\x06`@\x00\x01W\xde'
    显示数据形如：b'01066040000157de'
    
    python >----------------------------------------------------------> 串口调试助手
                    bytes.fromhex(str)                   serial.write()
    "A55A0001"字符串 ----------------->  b'\xa5Z\x00\x01' -------------> 串口显示：A5 5A 00 01
    
    python <----------------------------------------------------------< 串口调试助手
                binascii.b2a_hex(byte)                  serial.read()
    b'a55a0001' <--------------------- b'\xa5Z\x00\x01' <------------ 串口发送：A5 5A 00 01
    '''

    port = "com30"
    baudrate = 115200
    ser = serial.Serial()

    def com_init(self):
        self.ser.port = self.port
        self.ser.baudrate = self.baudrate
        self.ser.bytesize = 8
        self.ser.stopbits = 1
        self.ser.parity = 'N'
        self.ser.open()
        self.ser.timeout = 10  # 阻塞函数的超时时间，单位s，read(),readline()
        if (self.ser.isOpen()):
            print('*' * 20 + f"  串口：{self.ser.port}，打开成功，波特率：{self.ser.baudrate}  " + '*' * 20)
            return True
        else:
            print('*' * 20 + "  串口打开失败  " + '*' * 20)
            return False

    def com_close(self):
        self.ser.close()
        if (self.ser.isOpen()):
            print("串口关闭成功！")
        else:
            print("串口关闭失败")

    def com_send(self, send_data):
        if self.ser.isOpen():
            # self.ser.write(send_data.encode('utf-8'))
            self.ser.write(send_data)
            print(f"发送成功：{send_data}")
        else:
            print("发送失败")

    def com_read(self):
        if self.ser.isOpen():
            recv_data = self.ser.read_all()
            temp = recv_data.decode("utf-8")
            print(f"接收成功：{temp}")
        else:
            print("发送失败")

    def com_send_ex1(self):
        if self.ser.isOpen():
            send_data = "liuzhibiao123456789"
            # 串口接收到 ASCII "liuzhibiao123456789"
            # 即是十六进制：6C 69 75 7A 68 69 62 69 61 6F 31 32 33 34 35 36 37 38 39
            self.ser.write(send_data.encode('utf-8'))
            print(f"发送成功：{send_data}")
        else:
            print("发送失败")

    def com_send_ex2(self):
        if self.ser.isOpen():
            send_data = b"liuzhibiao123456789"
            # 串口接收到 ASCII "liuzhibiao123456789"
            # 即是十六进制：6C 69 75 7A 68 69 62 69 61 6F 31 32 33 34 35 36 37 38 39
            self.ser.write(send_data)
            print(f"发送成功：{send_data}")
        else:
            print("发送失败")

    def com_send_ex3(self):
        if self.ser.isOpen():
            send_data = "liuzhibiao123456789中文字符"
            # 串口接收到 ASCII "liuzhibiao123456789中文字符"
            # 即是十六进制：6C 69 75 7A 68 69 62 69 61 6F 31 32 33 34 35 36 37 38 39 D6 D0 CE C4 D7 D6 B7 FB
            self.ser.write(send_data.encode('gbk'))
            print(f"发送成功：{send_data}")
        else:
            print("发送失败")

    def com_send_ex4(self):
        if self.ser.isOpen():
            # Hex 发送
            send_data = bytes.fromhex('0B 0B')
            # 串口接收到 十六进制 0B 0B
            # 发送打印：b'\x0b\x0b'
            # 结论：发送诸如：b'\x0b\x0b'，才是我们想要的
            self.ser.write(send_data)
            print(f"发送成功：{send_data}")
        else:
            print("发送失败")

    def com_send_ex5(self):
        if self.ser.isOpen():
            # Hex 发送
            send_str = "A55A0001"
            # 串口收到：A5 5A 00 01
            # 串口发送：b'\xa5Z\x00\x01'
            send_data = bytes.fromhex(send_str)
            self.ser.write(send_data)
            print(f"发送成功：{send_data}")
        else:
            print("发送失败")

    def com_send_ex6(self):
        if self.ser.isOpen():
            # Hex 发送
            send_str = b"A55A00" + b"010d0a"
            # 串口收到：A5 5A 00 01 0D 0A
            # 串口发送：b'\xa5Z\x00\x01\r\n'
            send_data = binascii.a2b_hex(send_str)
            self.ser.write(send_data)
            print(f"发送成功：{send_data}")
        else:
            print("发送失败")

    def com_read_ex1(self):
        if self.ser.isOpen():
            # 非阻塞，立马读取所有
            recv_data = self.ser.read_all()
            temp = recv_data.decode("utf-8")
            print(f"接收成功：{temp}")
        else:
            print("发送失败")

    def com_read_ex2(self):
        if self.ser.isOpen():
            # 阻塞，读取指定字节跳出
            # 经过，timeout时间会超时！
            recv_data = self.ser.read(1024)
            temp = recv_data.decode("utf-8")
            print(f"接收成功：{temp}")
        else:
            print("发送失败")

    def com_read_ex3(self):
        if self.ser.isOpen():
            # 阻塞，接收到'\n'跳出
            recv_data = self.ser.readline()
            temp = recv_data.decode("utf-8")
            print(f"接收成功：{temp}")
        else:
            print("发送失败")

    def com_read_ex4(self):
        if self.ser.isOpen():
            # 接收hex，并解析
            recv_data = self.ser.read(8)
            print(f"接收原始数据：{recv_data}")
            temp = binascii.b2a_hex(recv_data)
            print(f"接收解析数据：{temp}")
        else:
            print("发送失败")

    def __init__(self):
        self.com_init()
        # self.com_send_ex1()
        # self.com_send_ex2()
        # self.com_send_ex3()
        # self.com_send_ex4()
        # self.com_send_ex5()
        self.com_send_ex6()
        # self.com_read_ex1()
        # self.com_read_ex2()
        # self.com_read_ex3()
        # self.com_read_ex4()


if __name__ == "__main__":
    c = COM()
